from flask import Blueprint, request
from passlib.context import CryptContext

from cfg.annotation.Transactional import session, transactional
from cfg.email.send_message import send_reset_message
from cfg.model.UserModel import UserModel
from cfg.repo.custom_error import CustomError
from cfg.token import generate_token

# /auth 访问前缀
bp = Blueprint("auth", __name__, url_prefix="/auth")
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")


# 登录
@bp.route("/login", methods=["POST"])
def login():
    """
    密码登录
    """
    email = request.args.get("email", type=str)
    old_password = request.args.get("password", type=str)
    if email is None or old_password is None:
        raise CustomError.user_pass_error()
    user = UserModel.query.filter(UserModel.email == email).first()
    if not user.password:
        raise CustomError.user_pass_error()
    # 验证密码
    is_valid = pwd_context.verify(old_password, user.password)
    if not is_valid:
        raise CustomError.user_pass_error()
    token = generate_token(user)
    return token


@bp.route("/register", methods=["POST"])
@transactional
def register():
    """
    注册账号
    """
    data = request.get_json()
    username = data.get("username")
    old_password = data.get("password")
    password = pwd_context.hash(old_password)
    email = data.get("email")
    age = data.get("age")
    gender = data.get("gender")
    tel = data.get("tel")
    user = UserModel(username=username, password=password, email=email, age=age, gender=gender, tel=tel)
    session.add(user)
    session.flush()
    if data is None:
        raise CustomError.register_data_error()
    return {
        "id": user.id,
        "username": user.username,
        "password": user.password,
        "email": user.email,
        "join_time": user.join_time,
        "age": user.age,
        "gender": user.gender,
        "tel": user.tel
    }


# @bp.route("/reset", methods=['POST'])
# @transactional
# def reset_password():
#     """
#     重置密码
#     """
@bp.route("/send", methods=['POST', 'GET'])
def send_message():
    email = request.args.get("email")
    send_reset_message(email)
